Skip to content

Conversation

@kylebarron
Copy link
Member

@kylebarron kylebarron commented Oct 8, 2025

Change list

  • Ensure that the default value of Map.basemap is MaplibreBasemap if no value of basemap was passed. Add a test for this.
  • Define various View classes to map to deck.gl views.
  • Define View models on the TS side.
  • When a GlobeView is passed, pass projection="globe" to Maplibre
  • Render a dark background on the canvas when in globe view
  • Add views parameter to Map. For now this only supports a single view instance, but hopefully in the future it'll support more.

This PR also sets the stage for non-geospatial map rendering and for multi-view support.

todo:

With this PR, to generate a map with globe view, someone would call

from lonboard import Map
from lonboard.view import GlobeView
from lonboard.basemap import MaplibreBasemap

lonboard.Map(
	layer,
	views=GlobeView(),
	basemap=MaplibreBasemap(mode="interleaved"),
)

Globe view:

image

Closes #886 (globe view), closes #375 (orthographic view) (though might need more work to allow non-spatial data)

Relates to

@vgeorge
Copy link
Member

vgeorge commented Oct 9, 2025

@kylebarron The general approach seems quite comprehensive. I’d suggest implementing the different modes more progressively, as this will likely require some refactoring on the JS side. In hindsight, adding XState wasn’t the best choice on my part, it makes state management a bit harder to evolve. I’ll open a ticket to propose an alternative. I think we can still address this technical debt while it’s not too complex, but not on this PR.

@kylebarron
Copy link
Member Author

I think despite what are a bunch of changes here on the Python side, the JS side only needs to change to support two modes: One with mapbox overlay and one without.

We can also merge this PR or something similar without exposing the classes to users, so we can keep developing on the JS side

@vgeorge
Copy link
Member

vgeorge commented Oct 10, 2025

@kylebarron sounds good. Now that we merged the Playwright PR we can add specs to ensure JS features continue to work as expected.

kylebarron added a commit that referenced this pull request Oct 14, 2025
…lay (#921)

As described in the [upstream deck.gl
docs](https://deck.gl/docs/developer-guide/base-maps/using-with-maplibre),
there are three ways to support using deck.gl with Maplibre:
_interleaved_, _overlaid_, and _reverse-controlled_. The first two are
supported via `MapboxOverlay` with a prop `interleaved: true|false`,
while the latter is implemented by having Maplibre be a child of the
deck.gl Map.

There are worthwhile reasons to support all of these modes. We need to
use interleaved or overlaid to support globe view, while
reverse-controlled better supports multiple deck.gl views.

This PR refactors the map component in `index.tsx` into two separate
React components: a deck.gl-first renderer (i.e. "reverse-controlled")
and a MapboxOverlay renderer.

The idea is that this will pair with #908 to give users more control
over various ways of rendering maps.

This is backwards-compatible because we default to reverse-controlled,
the existing default.

Closes #890, closes
#437, for
#886, for
#718
kylebarron added a commit that referenced this pull request Oct 15, 2025
A small refactor to make it easier to read `_map.py` by removing the
HTML export functionality, moving that to `_html_export.py`. This was
extracted from #908, see
https://github.com/developmentseed/lonboard/pull/908/files#r2414276602
@kylebarron
Copy link
Member Author

The basemap refactor was extracted to #935

@kylebarron kylebarron changed the title wip: Define models for Views feat: Define models for Views Oct 16, 2025
@github-actions github-actions bot added the feat label Oct 16, 2025
Comment on lines -20 to -22
async loadSubModels() {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unused.

@kylebarron kylebarron changed the title feat: Define models for Views feat: Support globe view Oct 17, 2025
@kylebarron kylebarron marked this pull request as ready for review October 17, 2025 00:03
@kylebarron kylebarron requested review from Copilot and vgeorge October 17, 2025 00:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for globe view rendering in lonboard by introducing a Views abstraction layer that maps to deck.gl's view system. The implementation allows users to specify different view types (Globe, Map, Orbit, etc.) and automatically configures the underlying rendering pipeline appropriately.

Key changes:

  • Created View class hierarchy (BaseView, GlobeView, MapView, etc.) to represent different deck.gl views
  • Added views parameter to Map class for specifying view instances
  • Updated default basemap behavior to use MaplibreBasemap() instead of None
  • Integrated view type detection to configure Maplibre projection mode and canvas background

Reviewed Changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lonboard/view.py Defines new View class hierarchy with FirstPersonView, GlobeView, MapView, OrbitView, and OrthographicView
lonboard/_map.py Adds views parameter and updates basemap default initialization
lonboard/types/map.py Updates MapKwargs TypedDict to include views parameter
lonboard/traits.py Updates ViewStateTrait validation signature to include Map type hint
src/model/view.ts Implements TypeScript view models that build deck.gl view instances
src/model/base.ts Removes unused loadSubModels method
src/model/extension.ts Removes call to removed loadSubModels method
src/index.tsx Integrates view state management and globe-specific styling
src/renderers/overlay.tsx Passes projection="globe" to Maplibre when using GlobeView
src/renderers/types.ts Updates MapRendererProps type to include views
src/util.ts Adds isGlobeView helper function
tests/test_map.py Adds test for default basemap behavior
eslint.config.js Reorganizes import statements alphabetically

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

kylebarron added a commit that referenced this pull request Oct 20, 2025
…ap` if no value of `basemap` was passed. (#963)

Extracted from #908 so
that `main` is clear
@kylebarron kylebarron added this to the 0.13 milestone Oct 22, 2025
@kylebarron kylebarron merged commit b2e6ae1 into main Oct 22, 2025
7 checks passed
@kylebarron kylebarron deleted the kyle/view-basemap-refactor branch October 22, 2025 03:24
kylebarron added a commit that referenced this pull request Oct 28, 2025
### Change list

- Adds definitions for map "controls" (which deck.gl calls "widgets",
but the name "widget" is too overloaded in the context of Jupyter, so
I'd like to call them "controls")
- Support for `ScaleControl`, `NavigationControl`, `FullscreenControl`
- These controls are supported by both deck.gl and maplibre, and so
implementations are defined for creating both the deck.gl and maplibre
counterparts

### Example

```py
from lonboard import Map
from lonboard.controls import ScaleControl, FullscreenControl, NavigationControl
from lonboard.basemap import MaplibreBasemap

m = Map([], 
    basemap=MaplibreBasemap(mode="overlaid"),
    controls=[ScaleControl(), FullscreenControl(), NavigationControl()]
)
m
```

<img width="734" height="506" alt="image"
src="https://github.com/user-attachments/assets/42fb5e55-57d8-4b2a-8fe2-f70b804dabce"
/>

We should probably change the default positioning of controls, move the
bbox selector, or make the bbox selector a control itself.

----

However, for deck.gl-driven rendering, I can only see the scale control:
<img width="756" height="611" alt="image"
src="https://github.com/user-attachments/assets/f8e6be57-55ec-45be-9c14-cf76b4ea64d0"
/>

Logged in #990

### Todo list

- Figure out how to pass these react components as children of the
`OverlayRenderer` or `DeckFirstRenderer` (depends on
#921)
- Use the refactored model initialization from
#923 to create the list
of control instances on the deck side
- Integrate more cleanly into the Python API (an extension of
#908)

Closes #842, relevant
to #681
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Maplibre GlobeView Add support for OrthographicView

3 participants